import { ApiCall } from 'tsrpc';
import { TsrpcErrorType } from 'tsrpc-proto';
import { GameError } from '../../domain/errors/GameError';

/**
 * API错误处理中间件
 * 统一处理所有API错误，确保客户端接收到一致的错误格式
 */
export class ErrorHandler {
    /**
     * 处理API调用中的错误
     * @param call API调用对象
     * @param error 错误对象
     */
    static handleApiError(call: ApiCall<any, any>, error: Error): void {
        console.error(`API Error in ${call.service.name}:`, error);

        if (GameError.isGameError(error)) {
            // 游戏业务错误
            this.handleGameError(call, error);
        } else if (error instanceof SyntaxError) {
            // JSON解析错误
            this.handleSyntaxError(call, error);
        } else if (error instanceof TypeError) {
            // 类型错误
            this.handleTypeError(call, error);
        } else {
            // 未知系统错误
            this.handleUnknownError(call, error);
        }
    }

    /**
     * 处理游戏业务错误
     */
    private static handleGameError(call: ApiCall<any, any>, error: GameError): void {
        const errorInfo = error.toDetailedInfo();
        
        // 记录详细错误日志
        console.error(`Game Error [${error.code}]:`, {
            message: error.message,
            context: error.context,
            stack: error.stack,
            api: call.service.name,
            timestamp: errorInfo.timestamp
        });

        // 返回客户端安全的错误信息
        call.error({
            message: error.message,
            code: error.code,
            type: this.mapStatusCodeToTsrpcErrorType(error.statusCode)
        });
    }

    /**
     * 处理JSON语法错误
     */
    private static handleSyntaxError(call: ApiCall<any, any>, error: SyntaxError): void {
        console.error('Syntax Error:', error);
        
        call.error({
            message: '请求格式错误',
            code: 'SYNTAX_ERROR',
            type: TsrpcErrorType.ClientError
        });
    }

    /**
     * 处理类型错误
     */
    private static handleTypeError(call: ApiCall<any, any>, error: TypeError): void {
        console.error('Type Error:', error);
        
        call.error({
            message: '参数类型错误',
            code: 'TYPE_ERROR',
            type: TsrpcErrorType.ClientError
        });
    }

    /**
     * 处理未知错误
     */
    private static handleUnknownError(call: ApiCall<any, any>, error: Error): void {
        console.error('Unknown Error:', error);
        
        call.error({
            message: '服务器内部错误',
            code: 'INTERNAL_SERVER_ERROR',
            type: TsrpcErrorType.ServerError
        });
    }

    /**
     * 将HTTP状态码映射到TSRPC错误类型
     */
    private static mapStatusCodeToTsrpcErrorType(statusCode: number): TsrpcErrorType {
        if (statusCode >= 400 && statusCode < 500) {
            return TsrpcErrorType.ClientError;
        } else if (statusCode >= 500) {
            return TsrpcErrorType.ServerError;
        } else {
            return TsrpcErrorType.ServerError;
        }
    }

    /**
     * 创建标准化的成功响应
     */
    static createSuccessResponse<T>(data: T, message?: string): {
        success: true;
        data: T;
        message?: string;
        timestamp: Date;
    } {
        return {
            success: true,
            data,
            message,
            timestamp: new Date()
        };
    }

    /**
     * 创建标准化的错误响应
     */
    static createErrorResponse(code: string, message: string): {
        success: false;
        code: string;
        message: string;
        timestamp: Date;
    } {
        return {
            success: false,
            code,
            message,
            timestamp: new Date()
        };
    }

    /**
     * 包装API处理器，自动进行错误处理
     */
    static wrapApiHandler<TReq, TRes>(
        handler: (call: ApiCall<TReq, TRes>) => Promise<void> | void
    ) {
        return async (call: ApiCall<TReq, TRes>) => {
            try {
                await handler(call);
            } catch (error) {
                this.handleApiError(call, error as Error);
            }
        };
    }

    /**
     * 验证必需参数
     */
    static validateRequiredParams(params: any, requiredFields: string[]): void {
        for (const field of requiredFields) {
            if (params[field] === undefined || params[field] === null) {
                throw new ValidationError(field, params[field], 'required');
            }
        }
    }

    /**
     * 验证参数类型
     */
    static validateParamType(value: any, expectedType: string, fieldName: string): void {
        const actualType = typeof value;
        if (actualType !== expectedType) {
            throw new ValidationError(fieldName, value, `expected ${expectedType}, got ${actualType}`);
        }
    }
}

/**
 * 参数验证错误类（临时定义，后续会移到专门的错误文件中）
 */
class ValidationError extends Error {
    public readonly code = 'VALIDATION_ERROR';
    public readonly statusCode = 400;

    constructor(field: string, value: any, constraint: string) {
        super(`参数验证失败：${field}=${value}，约束：${constraint}`);
    }
}
